﻿
using System;
using System.Collections.Generic;
using Windows.ApplicationModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Navigation;
using WinRTControl.Helpers;
namespace WinRTControl.Navigation
{
    internal sealed class Journal
    {
        #region Fields

        private readonly object _syncLock = new object();
        private JournalEntry _currentEntry;
        private Stack<JournalEntry> _forwardStack = new Stack<JournalEntry>();
        private Stack<JournalEntry> _backStack = new Stack<JournalEntry>();
        private bool _suppressNavigationEvent;
        internal event EventHandler<JournalEventArgs> Navigated;
      
        #endregion

        #region Properties

        internal bool CanGoBack
        {
            get
            {
                return this._backStack.Count > 0;
            }
        }
        internal bool CanGoForward
        {
            get
            {
                return this._forwardStack.Count > 0;
            }
        }

        internal JournalEntry CurrentEntry
        {
            get { return _currentEntry; }
        }

        internal Stack<JournalEntry> BackStack
        {
            get { return _backStack; }
        }

        internal Stack<JournalEntry> ForwardStack
        {
            get { return _forwardStack; }
        }

        internal Journal()
        {
        }

        #endregion

        #region Method

        //NEW
        internal void AddHistoryPoint(JournalEntry journalEntry)
        {
            Guard.AreNotNull(journalEntry, "journalEntry");
            lock (_syncLock)
            {
                _forwardStack.Clear();
                if (_currentEntry != null)
                {
                    _backStack.Push(_currentEntry);
                }
                _currentEntry = journalEntry;
            }
            UpdateObservables(journalEntry, NavigationMode.New);
        }

        //Back
        internal void GoBack()
        {
            if (!this.CanGoBack)
            {
                return;
            }
            lock (_syncLock)
            {
                _forwardStack.Push(this._currentEntry);
                _currentEntry = _backStack.Pop();
            }
            this.UpdateObservables(_currentEntry, NavigationMode.Back);
        }

        //Forward
        internal void GoForward()
        {
            if (!this.CanGoForward)
            {
                return;
            }
            lock (_syncLock)
            {
                _backStack.Push(_currentEntry);
                _currentEntry = _forwardStack.Pop();
            }
            this.UpdateObservables(_currentEntry, NavigationMode.Forward);
        }

        private void UpdateObservables(JournalEntry currentEntry, NavigationMode nNavigationMode)
        {
            this.OnNavigated(currentEntry.Name, currentEntry.Source, nNavigationMode);
        }

        protected void OnNavigated(string name, Uri uri, NavigationMode mode)
        {
            EventHandler<JournalEventArgs> navigated = this.Navigated;
            if (navigated != null)
            {
                JournalEventArgs journalEventArgs = new JournalEventArgs(name, uri, mode);
                navigated(this, journalEventArgs);
            }
        }

        #endregion
    }
}
